﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace VirtualCOM
{
    public static class VSPDManager
    {

        #region 常量

        private const string dllName = "VSPD\\vspdctl";

        #endregion

        #region 静态构造

        static VSPDManager()
        {
            //临时文件 每次启动后检测
            string tempFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), ".virtualCOM");
            //如果文件不存在认为是第一次启动
            if (!File.Exists(tempFile))
            {
                bool is64Bit = Is64Bit();
                if (is64Bit)
                    RunProcess(Path.Combine(Environment.CurrentDirectory, "VSPD\\NT6x64\\vsbsetup.exe"));
                else
                    RunProcess(Path.Combine(Environment.CurrentDirectory, "VSPD\\NT6\\vsbsetup.exe"));
                File.Create(tempFile);
            }
        }

        #endregion

        #region C++ API

        /// <summary>
        /// 创建串口对
        /// </summary>
        [DllImport(dllName, EntryPoint = "CreatePair", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool CreatePair([In][MarshalAs(UnmanagedType.LPStr)] string port1, [In][MarshalAs(UnmanagedType.LPStr)] string port2);

        /// <summary>
        /// 删除指定名称的串口对
        /// </summary>
        [DllImport(dllName, EntryPoint = "DeletePair", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool DeletePair([In][MarshalAs(UnmanagedType.LPStr)] string port);

        /// <summary>
        /// 删除所有串口对
        /// </summary>
        [DllImport(dllName, EntryPoint = "DeleteAll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool DeleteAll();

        #endregion

        #region Methods

        /// <summary>
        /// 检测是否为64位系统
        /// </summary>
        /// <returns></returns>
        private static bool Is64Bit()
        {
            try
            {
                string addressWidth = String.Empty;
                ConnectionOptions mConnOption = new ConnectionOptions();
                ManagementScope mMs = new ManagementScope("\\\\localhost", mConnOption);
                ObjectQuery mQuery = new ObjectQuery("select AddressWidth from Win32_Processor");
                ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(mMs, mQuery);
                ManagementObjectCollection mObjectCollection = mSearcher.Get();
                foreach (ManagementObject mObject in mObjectCollection)
                {
                    addressWidth = mObject["AddressWidth"].ToString();
                }
                return addressWidth == "64";
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 执行外部进程
        /// </summary>
        /// <param name="fileName"></param>
        private static void RunProcess(string fileName)
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = fileName;
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(fileName);
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();
            process.WaitForExit();//关键，等待外部程序退出后才能往下执行
        }

        /// <summary>
        /// 检测驱动是否已安装
        /// </summary>
        /// <returns></returns>
        private static bool DriverInstalled()
        {
            bool isInstall = false;
            try
            {
                System.Management.SelectQuery query = new System.Management.SelectQuery("Win32_SystemDriver");
                //query.Condition = "Name = 'SomeDriverName'";
                System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query);
                var drivers = searcher.Get();
                foreach (var item in drivers)
                {
                    string driverName = item["Name"].ToString();
                    System.Diagnostics.Trace.TraceInformation(driverName);
                    if (driverName.ToLower().Contains("vspd"))
                        isInstall = true;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError(ex.ToString());
            }
            return isInstall;
        }

        #endregion
    }
}
